package top.shaoxia.pwdm.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;
import org.springframework.web.bind.annotation.*;
import top.shaoxia.pwdm.pojo.AppResultDTO;
import top.shaoxia.pwdm.pojo.PwdmDetailsDO;
import top.shaoxia.pwdm.pojo.PwdmFolderDO;
import top.shaoxia.pwdm.service.PwdmDetailsService;
import top.shaoxia.pwdm.service.PwdmFolderService;

import javax.sql.DataSource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author wjc
 * @date 2022/2/17
 */
@RestController
@RequestMapping("/api")
public class PwdmController implements IController {
    private static final Logger log = LoggerFactory.getLogger(PwdmController.class);

    public static final String VERSION = "1.1";

    @Autowired
    private PwdmFolderService pwdmFolderService;
    @Autowired
    private PwdmDetailsService pwdmDetailsService;
    @Autowired
    private DataSource dataSource;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @RequestMapping("/version")
    public AppResultDTO gerVer() {
        AppResultDTO ard = new AppResultDTO(SUCCESS);
        Map<String, String> map = new HashMap<>();
        map.put("one", "密码小本本 Version " + VERSION);
        int year = LocalDateTime.now().getYear();
        String twoInfo = "Made in 树莓可乐+ice 2022";
        if (year > 2022) {
            twoInfo += "-" + year;
        }
        map.put("two", twoInfo);
        map.put("three", "基于Vue和Element Plus及其它开源软件");
        ard.setData(map);
        return ard;
    }

    /**
     * 获取登录信息
     *
     * @return
     */
    @RequestMapping("/auth")
    public AppResultDTO auth() {
        AppResultDTO ard = new AppResultDTO();
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            ard.setStatus(ERROR);
        } else {
            Object principal = authentication.getPrincipal();
            //判断是否登录
            if (principal instanceof User u) {
                ard.setStatus(SUCCESS);
                ard.setData(u.getUsername());
            } else {
                ard.setStatus(ERROR);
                ard.setMsg("没有登录");
            }
        }
        return ard;
    }

    /**
     * 修改密码
     *
     * @param oldPwd
     * @param newPwd
     * @return
     */
    @RequestMapping("/chg/pwd")
    public AppResultDTO chgPwd(@RequestParam String oldPwd, @RequestParam String newPwd) {
        AppResultDTO ard = new AppResultDTO();
        JdbcUserDetailsManager manager = new JdbcUserDetailsManager(dataSource);
        UserDetails userDetails = manager.loadUserByUsername(SecurityContextHolder.getContext().getAuthentication().getName());
        if (passwordEncoder.matches(oldPwd, userDetails.getPassword())) {
            manager.changePassword(oldPwd, passwordEncoder.encode(newPwd));
            ard.setStatus(SUCCESS);
        } else {
            ard.setStatus(ERROR);
            ard.setMsg("原密码不正确，密码修改失败");
        }
        return ard;
    }

    @RequestMapping("/folder/list")
    public AppResultDTO listFolders() {
        AppResultDTO ard = new AppResultDTO();
        try {
            List<PwdmFolderDO> list = pwdmFolderService.listAllFolders();
            ard.setStatus(SUCCESS);
            ard.setData(list);
        } catch (Exception e) {
            log.error("查询文件夹列表异常", e);
            ard.setStatus(ERROR);
            ard.setMsg("查询文件夹列表异常");
        }
        return ard;
    }

    @RequestMapping("/folder/query")
    public AppResultDTO queryFolders(@RequestBody PwdmFolderDO folderDO) {
        AppResultDTO ard = new AppResultDTO();
        PwdmFolderDO find = pwdmFolderService.selectById(folderDO);
        ard.setStatus(SUCCESS);
        ard.setData(find);
        return ard;
    }


    @RequestMapping("/folder/add")
    public AppResultDTO addFolder(@RequestBody PwdmFolderDO folderDO) {
        AppResultDTO ard = new AppResultDTO();
        try {
            folderDO.setSn(9999);
            PwdmFolderDO insert = pwdmFolderService.insert(folderDO);
            ard.setStatus(SUCCESS);
            ard.setData(insert);
        } catch (Exception e) {
            log.error("新增文件夹异常", e);
            ard.setStatus(ERROR);
            ard.setMsg("请检查文件夹名是否重复");
        }
        return ard;
    }

    @RequestMapping("/folder/del")
    public AppResultDTO delFolder(@RequestBody PwdmFolderDO folderDO) {
        AppResultDTO ard = new AppResultDTO();
        pwdmFolderService.delete(folderDO);
        ard.setStatus(SUCCESS);
        return ard;
    }

    @RequestMapping("/details/list")
    public AppResultDTO listDetails(@RequestBody PwdmDetailsDO detailsDO) {
        AppResultDTO ard = new AppResultDTO();
        List<PwdmDetailsDO> list = pwdmDetailsService.listAllDetails(detailsDO);
        ard.setStatus(SUCCESS);
        ard.setData(list);
        return ard;
    }

    @RequestMapping("/details/save")
    public AppResultDTO saveDetails(@RequestBody PwdmDetailsDO detailsDO) {
        AppResultDTO ard = new AppResultDTO();
        detailsDO.setUpdateTime(LocalDateTime.now());
        try {
            PwdmDetailsDO newDetails = pwdmDetailsService.save(detailsDO);
            ard.setStatus(SUCCESS);
            ard.setData(newDetails);
        } catch (Exception e) {
            log.error("新增项目异常", e);
            ard.setStatus(ERROR);
            ard.setMsg("请检查项目名称是否重复");
        }
        return ard;
    }

    @RequestMapping("/details/delete")
    public AppResultDTO deleteDetails(@RequestBody PwdmDetailsDO detailsDO) {
        AppResultDTO ard = new AppResultDTO();
        pwdmDetailsService.delete(detailsDO);
        ard.setStatus(SUCCESS);
        return ard;
    }
}
